using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using SelectDevice;
using SMD2XX;

namespace BitBangTest
{
    public partial class Form1 : Form
    {
        /* 
         * The BBUSB allows access to 12 pins that can be configured individually
         * as either input or output. 8 of these pins are refered to as pins D0 to D7
         * while the remaining 4 are referred to as pins C0 to C3 (CBUS pins).
         * The D0-D7 pins I/O state is set using the setMode function. The CBUS
         * pins must first be set to the I/O mode in EEPROM, then their I/O state
         * can also be set using the setMode function. CBUS4 is not configurable for
         * I/O.
         * 
         * Select Pin State
         * Pin I/O states are selected in the topmost row of buttons.
         * Each button is labeled with the corresponding pin name and clicking the 
         * button will toggle the pin I/O state and show that state as either an 'I'
         * or 'O'.
         * 
         * Toggle Output Pin Logic Level
         * The second row uses buttons with virtual switch images. If the pins I/O 
         * state is for output, clicking the button will toggle ON and OFF changing 
         * the logic level on the pin. If the pin I/O state is for input, the button 
         * will not be clickable and will appear grayed out.
         * 
         * 
         * Read Input Pin Logic Level
         * Pins with their I/O state set to input will be read and the state will be
         * shown in the bottom row by showing a virtual LED as either an OFF or ON image.
         * Pins with their I/O state set to output will show a light gray LED image.
         * 
         * Revision History
         * Version 1.0 Joe Pardue 6/3/07
         * 
         */

        #region Intitialization

        FT_STATUS ftStatus = 0;
        private UInt32 handle = 0;

        SM_D2XX SM = new SM_D2XX();

        Select_Device dev = new Select_Device();      

        // Constants for logic levels
        private const bool ON = true;
        private const bool OFF = false;

        private byte Input = 0;
        private int Output = 0;
        private byte InputC = 0;
        private int OutputC = 0XF0; // Starts with C pins as output

        private bool UseDBus = true; // If false, use CBUS

        // Constants to indicate pin state
        private const bool State_In = true;
        private const bool State_Out = false;

        // Pin State Variables
        private bool D0_IO_State = State_Out;
        private bool D0_OnOff_State = OFF;

        private bool D1_IO_State = State_Out;
        private bool D1_OnOff_State = OFF;

        private bool D2_IO_State = State_Out;
        private bool D2_OnOff_State = OFF;

        private bool D3_IO_State = State_Out;
        private bool D3_OnOff_State = OFF;

        private bool D4_IO_State = State_Out;
        private bool D4_OnOff_State = OFF;

        private bool D5_IO_State = State_Out;
        private bool D5_OnOff_State = OFF;
        
        private bool D6_IO_State = State_Out;
        private bool D6_OnOff_State = OFF;
        
        private bool D7_IO_State = State_Out;
        private bool D7_OnOff_State = OFF;

        private bool C0_IO_State = State_Out;
        private bool C0_OnOff_State = OFF;

        private bool C1_IO_State = State_Out;
        private bool C1_OnOff_State = OFF;

        private bool C2_IO_State = State_Out;
        private bool C2_OnOff_State = OFF;

        private bool C3_IO_State = State_Out;
        private bool C3_OnOff_State = OFF;

        public Form1()
        {
            InitializeComponent();

            LED0.image = (int)LED.LED22.LEDColor.Disabled;
            buttonSD0.ImageIndex = 0;
            buttonSD0.Show();

            LED1.image = (int)LED.LED22.LEDColor.Disabled;
            buttonSD1.ImageIndex = 0;
            buttonSD1.Show();

            LED2.image = (int)LED.LED22.LEDColor.Disabled;
            buttonSD2.ImageIndex = 0;
            buttonSD2.Show();

            LED3.image = (int)LED.LED22.LEDColor.Disabled;
            buttonSD3.ImageIndex = 0;
            buttonSD3.Show();

            LED4.image = (int)LED.LED22.LEDColor.Disabled;
            buttonSD4.ImageIndex = 0;
            buttonSD4.Show();

            LED5.image = (int)LED.LED22.LEDColor.Disabled;
            buttonSD5.ImageIndex = 0;
            buttonSD5.Show();

            LED6.image = (int)LED.LED22.LEDColor.Disabled;
            buttonSD6.ImageIndex = 0;
            buttonSD6.Show();

            LED7.image = (int)LED.LED22.LEDColor.Disabled;
            buttonSD7.ImageIndex = 0;
            buttonSD7.Show();

            LEDC0.image = (int)LED.LED22.LEDColor.Disabled;
            buttonSC0.ImageIndex = 0;
            buttonSC0.Show();

            LEDC1.image = (int)LED.LED22.LEDColor.Disabled;
            buttonSC1.ImageIndex = 0;
            buttonSC1.Show();

            LEDC2.image = (int)LED.LED22.LEDColor.Disabled;
            buttonSC2.ImageIndex = 0;
            buttonSC2.Show();

            LEDC3.image = (int)LED.LED22.LEDColor.Disabled;
            buttonSC3.ImageIndex = 0;
            buttonSC3.Show();

            groupBoxDBUS.Enabled = true;
            groupBoxCBUS.Enabled = false;

        }
        #endregion

        #region Menu Items

        #region Bus select toggle
        private void useDBusToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (UseDBus)
            {
                UseDBus = false; // Use C BUS
                useDBusToolStripMenuItem.Text = "Use C BUS";
                groupBoxDBUS.Enabled = false;
                groupBoxCBUS.Enabled = true;
            }
            else
            {
                UseDBus = true; // Use D BUS
                useDBusToolStripMenuItem.Text = "Use D BUS";
                groupBoxDBUS.Enabled = true;
                groupBoxCBUS.Enabled = false;
            }
        }
        #endregion

        #region Select and Open a Device

        private void selectDeviceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            dev.ShowDialog();

            switch (dev.OpenBy)
            {
                case (uint)OPENBY.SERIAL_NUMBER: // use OpenEX
                    openBySerialNumber(dev.SerialNumber);
                    break;
                case (uint)OPENBY.DESCRIPTION: // use OpenEX
                    openByDescription(dev.Description);
                    break;
                case (uint)OPENBY.LOCATIONID: // use OpenEX
                    openByLocationID(dev.LocID);
                    break;
                default:
                    MessageBox.Show("ERROR - OpenBy = " + dev.OpenBy.ToString());
                    break;
            }
        }

        // open by serial number
        private void openBySerialNumber(string SN)
        {
            ftStatus = SM.openSerialNumber(SN, ref handle);
            if (ftStatus != FT_STATUS.FT_OK)
            {
                MessageBox.Show("Error: buttonGet_Click failed to open device");
            }
        }

        // open by description
        private void openByDescription(string description)
        {
            ftStatus = SM.openDescription(description, ref handle);
            if (ftStatus != FT_STATUS.FT_OK)
            {
                MessageBox.Show("Error: buttonGet_Click failed to open port");
            }
        }

        // open by location
        private void openByLocationID(UInt32 locID)
        {
            ftStatus = SM.openLocationID(locID, ref handle);
            if (ftStatus != FT_STATUS.FT_OK)
            {
                MessageBox.Show("Error: buttonGet_Click failed to open port");
            }
        }

        // Assumes device is open
        private void closeDevice()
        {
            SM.closeDevice(handle);
        }

        #endregion

        #endregion

        #region Set I/O State

        private void buttonD0_Click(object sender, EventArgs e)
        {
            if (D0_IO_State == State_In)
            {
                D0_IO_State = State_Out;
                buttonD0.Text = "Out";
                buttonSD0.Enabled = true;
                LED0.image = (int)LED.LED22.LEDColor.Disabled;
                if (getOutputBit0()) { labelD0.Text = "1"; } else { labelD0.Text = "0"; }
            }
            else
            {
                D0_IO_State = State_In;
                buttonD0.Text = "In";
                buttonSD0.Enabled = false;
                LED0.image = (int)LED.LED22.LEDColor.RedOff;
                labelD0.Text = "X";
            }
        }
        private void buttonD1_Click(object sender, EventArgs e)
        {
            if (D1_IO_State == State_In)
            {
                D1_IO_State = State_Out;
                buttonD1.Text = "Out";
                buttonSD1.Enabled = true;
                LED1.image = (int)LED.LED22.LEDColor.Disabled;
                if (getOutputBit1()) { labelD1.Text = "1"; } else { labelD1.Text = "0"; }
            }
            else
            {
                D1_IO_State = State_In;
                buttonD1.Text = "In";
                buttonSD1.Enabled = false;
                LED1.image = (int)LED.LED22.LEDColor.RedOff;
                labelD1.Text = "X";
            }
        }
        private void buttonD2_Click(object sender, EventArgs e)
        {
            if (D2_IO_State == State_In)
            {
                D2_IO_State = State_Out;
                buttonD2.Text = "Out";
                buttonSD2.Enabled = true;
                LED2.image = (int)LED.LED22.LEDColor.Disabled;
                if (getOutputBit2()) { labelD2.Text = "1"; } else { labelD2.Text = "0"; }
            }
            else
            {
                D2_IO_State = State_In;
                buttonD2.Text = "In";
                buttonSD2.Enabled = false;
                LED2.image = (int)LED.LED22.LEDColor.RedOff;
                labelD2.Text = "X";
            }
        }

        private void buttonD3_Click(object sender, EventArgs e)
        {
            if (D3_IO_State == State_In)
            {
                D3_IO_State = State_Out;
                buttonD3.Text = "Out";
                buttonSD3.Enabled = true;
                LED3.image = (int)LED.LED22.LEDColor.Disabled;
                if (getOutputBit3()) { labelD3.Text = "1"; } else { labelD3.Text = "0"; }
            }
            else
            {
                D3_IO_State = State_In;
                buttonD3.Text = "In";
                buttonSD3.Enabled = false;
                LED3.image = (int)LED.LED22.LEDColor.RedOff;
                labelD3.Text = "X";
            }
        }

        private void buttonD4_Click(object sender, EventArgs e)
        {
            if (D4_IO_State == State_In)
            {
                D4_IO_State = State_Out;
                buttonD4.Text = "Out";
                buttonSD4.Enabled = true;
                LED4.image = (int)LED.LED22.LEDColor.Disabled;
                if (getOutputBit4()) { labelD4.Text = "1"; } else { labelD4.Text = "0"; }
            }
            else
            {
                D4_IO_State = State_In;
                buttonD4.Text = "In";
                buttonSD4.Enabled = false;
                LED4.image = (int)LED.LED22.LEDColor.RedOff;
                labelD4.Text = "X";
            }
        }

        private void buttonD5_Click(object sender, EventArgs e)
        {
            if (D5_IO_State == State_In)
            {
                D5_IO_State = State_Out;
                buttonD5.Text = "Out";
                buttonSD5.Enabled = true;
                LED5.image = (int)LED.LED22.LEDColor.Disabled;
                if (getOutputBit5()) { labelD5.Text = "1"; } else { labelD5.Text = "0"; }
            }
            else
            {
                D5_IO_State = State_In;
                buttonD5.Text = "In";
                buttonSD5.Enabled = false;
                LED5.image = (int)LED.LED22.LEDColor.RedOff;
                labelD5.Text = "X";
            }
        }

        private void buttonD6_Click(object sender, EventArgs e)
        {
            if (D6_IO_State == State_In)
            {
                D6_IO_State = State_Out;
                buttonD6.Text = "Out";
                buttonSD6.Enabled = true;
                LED6.image = (int)LED.LED22.LEDColor.Disabled;
                if (getOutputBit6()) { labelD6.Text = "1"; } else { labelD6.Text = "0"; }
            }
            else
            {
                D6_IO_State = State_In;
                buttonD6.Text = "In";
                buttonSD6.Enabled = false;
                LED6.image = (int)LED.LED22.LEDColor.RedOff;
                labelD6.Text = "X";
            }
        }

        private void buttonD7_Click(object sender, EventArgs e)
        {
            if (D7_IO_State == State_In)
            {
                D7_IO_State = State_Out;
                buttonD7.Text = "Out";
                buttonSD7.Enabled = true;
                LED7.image = (int)LED.LED22.LEDColor.Disabled;
                if (getOutputBit1()) { labelD7.Text = "1"; } else { labelD7.Text = "0"; }
            }
            else
            {
                D7_IO_State = State_In;
                buttonD7.Text = "In";
                buttonSD7.Enabled = false;
                LED7.image = (int)LED.LED22.LEDColor.RedOff;
                labelD7.Text = "X";
            }
        }

        private void buttonC0_Click(object sender, EventArgs e)
        {
            if (C0_IO_State == State_In)
            {
                C0_IO_State = State_Out;
                buttonC0.Text = "Out";
                buttonSC0.Enabled = true;
                LEDC0.image = (int)LED.LED22.LEDColor.Disabled;
            }
            else
            {
                C0_IO_State = State_In;
                buttonC0.Text = "In";
                buttonSC0.Enabled = false;
                LEDC0.image = (int)LED.LED22.LEDColor.RedOff;
                labelC0.Text = "X";
            }
        }

        private void buttonC1_Click(object sender, EventArgs e)
        {
            if (C1_IO_State == State_In)
            {
                C1_IO_State = State_Out;
                buttonC1.Text = "Out";
                buttonSC1.Enabled = true;
                LEDC1.image = (int)LED.LED22.LEDColor.Disabled;
            }
            else
            {
                C1_IO_State = State_In;
                buttonC1.Text = "In";
                buttonSC1.Enabled = false;
                LEDC1.image = (int)LED.LED22.LEDColor.RedOff;
                labelC1.Text = "X";
            }
        }

        private void buttonC2_Click(object sender, EventArgs e)
        {
            if (C2_IO_State == State_In)
            {
                C2_IO_State = State_Out;
                buttonC2.Text = "Out";
                buttonSC2.Enabled = true;
                LEDC2.image = (int)LED.LED22.LEDColor.Disabled;
                if (getOutputBitC2()) { labelC2.Text = "1"; } else { labelC2.Text = "0"; }
            }
            else
            {
                C2_IO_State = State_In;
                buttonC2.Text = "In";
                buttonSC2.Enabled = false;
                LEDC2.image = (int)LED.LED22.LEDColor.RedOff;
                labelC2.Text = "X";
            }
        }

        private void buttonC3_Click(object sender, EventArgs e)
        {
            if (C3_IO_State == State_In)
            {
                C3_IO_State = State_Out;
                buttonC3.Text = "Out";
                buttonSC3.Enabled = true;
                LEDC3.image = (int)LED.LED22.LEDColor.Disabled;
            }
            else
            {
                C3_IO_State = State_In;
                buttonC3.Text = "In";
                buttonSC3.Enabled = false;
                LEDC3.image = (int)LED.LED22.LEDColor.RedOff;
                labelC3.Text = "X";
            }
        }

        #endregion

        #region Toggle Output Logic Levels

        private void buttonSD0_Click(object sender, EventArgs e)
        {
            if (D0_IO_State == State_Out)
            {
                if (D0_OnOff_State == ON)
                {
                    D0_OnOff_State = OFF;
                    buttonSD0.ImageIndex = 0;
                    labelD0.Text = "0";
                    if(Output >= 1 )Output -= 1;
                }
                else
                {
                    D0_OnOff_State = ON;
                    buttonSD0.ImageIndex = 1;
                    labelD0.Text = "1";
                    Output += 1;
                }
                bitBangOutD((byte)Output);
            }
        }

        private void buttonSD1_Click(object sender, EventArgs e)
        {
            if (D1_IO_State == State_Out)
            {
                if (D1_OnOff_State == ON)
                {
                    D1_OnOff_State = OFF;
                    buttonSD1.ImageIndex = 0;
                    labelD1.Text = "0";
                    if (Output >= 2) Output -= 2;
                }
                else
                {
                    D1_OnOff_State = ON;
                    buttonSD1.ImageIndex = 1;
                    labelD1.Text = "1";
                    Output += 2;
                }
                bitBangOutD((byte)Output);
            }
        }

        private void buttonSD2_Click(object sender, EventArgs e)
        {
            if (D2_IO_State == State_Out)
            {
                if (D2_OnOff_State == ON)
                {
                    D2_OnOff_State = OFF;
                    buttonSD2.ImageIndex = 0;
                    labelD2.Text = "0";
                    if (Output >= 4) Output -= 4;
                }
                else
                {
                    D2_OnOff_State = ON;
                    buttonSD2.ImageIndex = 1;
                    labelD2.Text = "1";
                    Output += 4;
                }
                bitBangOutD((byte)Output);
            }
        }
        private void buttonSD3_Click(object sender, EventArgs e)
        {
            if (D3_IO_State == State_Out)
            {
                if (D3_OnOff_State == ON)
                {
                    D3_OnOff_State = OFF;
                    buttonSD3.ImageIndex = 0;
                    labelD3.Text = "0";
                    if (Output >= 8) Output -= 8;
                }
                else
                {
                    D3_OnOff_State = ON;
                    buttonSD3.ImageIndex = 1;
                    labelD3.Text = "1";
                    Output += 8;
                }
                bitBangOutD((byte)Output);
            }
        }

        private void buttonSD4_Click(object sender, EventArgs e)
        {
            if (D4_IO_State == State_Out)
            {
                if (D4_OnOff_State == ON)
                {
                    D4_OnOff_State = OFF;
                    buttonSD4.ImageIndex = 0;
                    labelD4.Text = "0";
                    if (Output >= 16) Output -= 16;
                }
                else
                {
                    D4_OnOff_State = ON;
                    buttonSD4.ImageIndex = 1;
                    labelD4.Text = "1";
                    Output += 16;
                }
                bitBangOutD((byte)Output);
            }
        }

        private void buttonSD5_Click(object sender, EventArgs e)
        {
            if (D5_IO_State == State_Out)
            {
                if (D5_OnOff_State == ON)
                {
                    D5_OnOff_State = OFF;
                    buttonSD5.ImageIndex = 0;
                    labelD5.Text = "0";
                    if (Output >= 32) Output -= 32;
                }
                else
                {
                    D5_OnOff_State = ON;
                    buttonSD5.ImageIndex = 1;
                    labelD5.Text = "1";
                    Output += 32;
                }
                bitBangOutD((byte)Output);
            }
        }

        private void buttonSD6_Click(object sender, EventArgs e)
        {
            if (D6_IO_State == State_Out)
            {
                if (D6_OnOff_State == ON)
                {
                    D6_OnOff_State = OFF;
                    buttonSD6.ImageIndex = 0;
                    labelD6.Text = "0";
                    if (Output >= 64) Output -= 64;
                }
                else
                {
                    D6_OnOff_State = ON;
                    buttonSD6.ImageIndex = 1;
                    labelD6.Text = "1";
                    Output += 64;
                }
                bitBangOutD((byte)Output);
            }
        }

        private void buttonSD7_Click(object sender, EventArgs e)
        {
            if (D7_IO_State == State_Out)
            {
                if (D7_OnOff_State == ON)
                {
                    D7_OnOff_State = OFF;
                    buttonSD7.ImageIndex = 0;
                    labelD7.Text = "0";
                    if (Output >= 128) Output -= 128;
                }
                else
                {
                    D7_OnOff_State = ON;
                    buttonSD7.ImageIndex = 1;
                    labelD7.Text = "1";
                    Output += 128;
                }
                bitBangOutD((byte)Output);
            }
        }

        private void buttonSC0_Click(object sender, EventArgs e)
        {
            if (C0_IO_State == State_Out)
            {
                if (C0_OnOff_State == ON)
                {
                    C0_OnOff_State = OFF;
                    buttonSC0.ImageIndex = 0;
                    labelC0.Text = "0";
                    if (OutputC >= 1) OutputC -= 1;
                }
                else
                {
                    C0_OnOff_State = ON;
                    buttonSC0.ImageIndex = 1;
                    labelC0.Text = "1";
                    OutputC += 1;
                }
                bitBangOutC((byte)OutputC);
            }
        }

        private void buttonSC1_Click(object sender, EventArgs e)
        {
            if (C1_IO_State == State_Out)
            {
                if (C1_OnOff_State == ON)
                {
                    C1_OnOff_State = OFF;
                    buttonSC1.ImageIndex = 0;
                    labelC1.Text = "0";
                    if (OutputC >= 2) OutputC -= 2;
                }
                else
                {
                    C1_OnOff_State = ON;
                    buttonSC1.ImageIndex = 1;
                    labelC1.Text = "1";
                    OutputC += 2;
                }
                bitBangOutC((byte)OutputC);
            }
        }

        private void buttonSC2_Click(object sender, EventArgs e)
        {
            if (C2_IO_State == State_Out)
            {
                if (C2_OnOff_State == ON)
                {
                    C2_OnOff_State = OFF;
                    buttonSC2.ImageIndex = 0;
                    labelC2.Text = "0";
                    if (OutputC >= 4) OutputC -= 4;
                }
                else
                {
                    C2_OnOff_State = ON;
                    buttonSC2.ImageIndex = 1;
                    labelC2.Text = "1";
                    OutputC += 4;
                }
                bitBangOutC((byte)OutputC);
            }
        }

        private void buttonSC3_Click(object sender, EventArgs e)
        {
            if (C3_IO_State == State_Out)
            {
                if (C3_OnOff_State == ON)
                {
                    C3_OnOff_State = OFF;
                    buttonSC3.ImageIndex = 0;
                    labelC3.Text = "0";
                    if (OutputC >= 8) OutputC -= 8;
                }
                else
                {
                    C3_OnOff_State = ON;
                    buttonSC3.ImageIndex = 1;
                    labelC3.Text = "1";
                    OutputC += 8;
                }
                bitBangOutC((byte)OutputC);
            }
        }
        #endregion

        #region Get Input Bits

        private bool getInputBit0()
        {
            byte bit0 = (byte)Input;

            bit0 = (byte)(bit0 << 7);
            bit0 = (byte)(bit0 >> 7);

            if (bit0 == 1) return true;
            else return false;
        }
        private bool getInputBit1()
        {
            byte bit1 = (byte)Input;

            bit1 = (byte)(bit1 << 6);
            bit1 = (byte)(bit1 >> 7);

            if (bit1 == 1) return true;
            else return false;
        }
        private bool getInputBit2()
        {
            byte bit2 = (byte)Input;

            bit2 = (byte)(bit2 << 5);
            bit2 = (byte)(bit2 >> 7);

            if (bit2 == 1) return true;
            else return false;
        }

        private bool getInputBit3()
        {
            byte bit3 = (byte)Input;

            bit3 = (byte)(bit3 << 4);
            bit3 = (byte)(bit3 >> 7);

            if (bit3 == 1) return true;
            else return false;
        }

        private bool getInputBit4()
        {
            byte bit4 = (byte)Input;

            bit4 = (byte)(bit4 << 3);
            bit4 = (byte)(bit4 >> 7);

            if (bit4 == 1) return true;
            else return false;
        }

        private bool getInputBit5()
        {
            byte bit5 = (byte)Input;

            bit5 = (byte)(bit5 << 2);
            bit5 = (byte)(bit5 >> 7);

            if (bit5 == 1) return true;
            else return false;
        }

        private bool getInputBit6()
        {
            byte bit6 = (byte)Input;

            bit6 = (byte)(bit6 << 1);
            bit6 = (byte)(bit6 >> 7);

            if (bit6 == 1) return true;
            else return false;
        }

        private bool getInputBit7()
        {
            byte bit7 = (byte)Input;

            bit7 = (byte)(bit7 >> 7);

            if (bit7 == 1) return true;
            else return false;
        }

        private bool getInputBitC0()
        {
            byte bit0 = (byte)InputC;

            bit0 = (byte)(bit0 << 7);
            bit0 = (byte)(bit0 >> 7);

            if (bit0 == 1) return true;
            else return false;
        }
        private bool getInputBitC1()
        {
            byte bit1 = (byte)InputC;

            bit1 = (byte)(bit1 << 6);
            bit1 = (byte)(bit1 >> 7);

            if (bit1 == 1) return true;
            else return false;
        }
        private bool getInputBitC2()
        {
            byte bit2 = (byte)InputC;

            bit2 = (byte)(bit2 << 5);
            bit2 = (byte)(bit2 >> 7);

            if (bit2 == 1) return true;
            else return false;
        }

        private bool getInputBitC3()
        {
            byte bit3 = (byte)InputC;

            bit3 = (byte)(bit3 << 4);
            bit3 = (byte)(bit3 >> 7);

            if (bit3 == 1) return true;
            else return false;
        }
        #endregion

        #region Get Output Bits

        private bool getOutputBit0()
        {
            byte bit0 = (byte)Output;

            bit0 = (byte)(bit0 << 7);
            bit0 = (byte)(bit0 >> 7);

            if (bit0 == 1) return true;
            else return false;
        }
        private bool getOutputBit1()
        {
            byte bit1 = (byte)Output;

            bit1 = (byte)(bit1 << 6);
            bit1 = (byte)(bit1 >> 7);

            if (bit1 == 1) return true;
            else return false;
        }
        private bool getOutputBit2()
        {
            byte bit2 = (byte)Output;

            bit2 = (byte)(bit2 << 5);
            bit2 = (byte)(bit2 >> 7);

            if (bit2 == 1) return true;
            else return false;
        }

        private bool getOutputBit3()
        {
            byte bit3 = (byte)Output;

            bit3 = (byte)(bit3 << 4);
            bit3 = (byte)(bit3 >> 7);

            if (bit3 == 1) return true;
            else return false;
        }

        private bool getOutputBit4()
        {
            byte bit4 = (byte)Output;

            bit4 = (byte)(bit4 << 3);
            bit4 = (byte)(bit4 >> 7);

            if (bit4 == 1) return true;
            else return false;
        }

        private bool getOutputBit5()
        {
            byte bit5 = (byte)Output;

            bit5 = (byte)(bit5 << 2);
            bit5 = (byte)(bit5 >> 7);

            if (bit5 == 1) return true;
            else return false;
        }

        private bool getOutputBit6()
        {
            byte bit6 = (byte)Output;

            bit6 = (byte)(bit6 << 1);
            bit6 = (byte)(bit6 >> 7);

            if (bit6 == 1) return true;
            else return false;
        }

        private bool getOutputBit7()
        {
            byte bit7 = (byte)Output;

            bit7 = (byte)(bit7 >> 7);

            if (bit7 == 1) return true;
            else return false;
        }

        private bool getOutputBitC0()
        {
            byte bit0 = (byte)OutputC;

            bit0 = (byte)(bit0 << 7);
            bit0 = (byte)(bit0 >> 7);

            if (bit0 == 1) return true;
            else return false;
        }
        private bool getOutputBitC1()
        {
            byte bit1 = (byte)OutputC;

            bit1 = (byte)(bit1 << 6);
            bit1 = (byte)(bit1 >> 7);

            if (bit1 == 1) return true;
            else return false;
        }
        private bool getOutputBitC2()
        {
            byte bit2 = (byte)OutputC;

            bit2 = (byte)(bit2 << 5);
            bit2 = (byte)(bit2 >> 7);

            if (bit2 == 1) return true;
            else return false;
        }

        private bool getOutputBitC3()
        {
            byte bit3 = (byte)OutputC;

            bit3 = (byte)(bit3 << 4);
            bit3 = (byte)(bit3 >> 7);

            if (bit3 == 1) return true;
            else return false;
        }
        #endregion

        #region Read Bus

        private void buttonReadDBus_Click(object sender, EventArgs e)
        { 
            SM.bitBang_GetBitMode(handle, ref Input);

            if (D0_IO_State == State_In)
            {
                if (getInputBit0()) { LED0.image = (int)LED.LED22.LEDColor.RedOff; }
                else {LED0.image = (int)LED.LED22.LEDColor.RedOn; }
            }

            if (D1_IO_State == State_In)
            {
                if (getInputBit1()) { LED1.image = (int)LED.LED22.LEDColor.RedOff; }
                else {  LED1.image = (int)LED.LED22.LEDColor.RedOn; }
            }

            if (D2_IO_State == State_In)
            {
                if (getInputBit2()) { LED2.image = (int)LED.LED22.LEDColor.RedOff; }
                else { LED2.image = (int)LED.LED22.LEDColor.RedOn; }
            }

            if (D3_IO_State == State_In)
            {
                if (getInputBit3()) { LED3.image = (int)LED.LED22.LEDColor.RedOff; }
                else { LED3.image = (int)LED.LED22.LEDColor.RedOn; }
            }

            if (D4_IO_State == State_In)
            {
                if (getInputBit4()) { LED4.image = (int)LED.LED22.LEDColor.RedOff; }
                else { LED4.image = (int)LED.LED22.LEDColor.RedOn; }
            }

            if (D5_IO_State == State_In)
            {
                if (getInputBit5()) { LED5.image = (int)LED.LED22.LEDColor.RedOff; }
                else { LED5.image = (int)LED.LED22.LEDColor.RedOn; }
            }

            if (D6_IO_State == State_In)
            {
                if (getInputBit6()) { LED6.image = (int)LED.LED22.LEDColor.RedOff; }
                else { LED6.image = (int)LED.LED22.LEDColor.RedOn; }
            }

            if (D7_IO_State == State_In)
            {
                if (getInputBit7()) { LED7.image = (int)LED.LED22.LEDColor.RedOff; }
                else { LED7.image = (int)LED.LED22.LEDColor.RedOn; }
            }
        }

        private void buttonReadCBus_Click(object sender, EventArgs e)
        {
            // Set CBUS pins to I/O state
            byte temp = 0;
            
            if (C0_IO_State == State_Out)
            {
                temp += 16;
            }

            if (C1_IO_State == State_Out)
            {
                temp += 32;
            }

            if (C0_IO_State == State_Out)
            {
                temp += 64;
            }

            if (C0_IO_State == State_Out)
            {
                temp += 128;
            }

            // Set to input on CBUS pins
            SM.bitBang_SetBitMode(handle, temp, 0x20);

            // Read the input
            SM.bitBang_GetBitMode(handle, ref InputC);

            if (C0_IO_State == State_In)
            {
                if (getInputBitC0()) { LEDC0.image = (int)LED.LED22.LEDColor.RedOff; }
                else { LEDC0.image = (int)LED.LED22.LEDColor.RedOn; }
            }

            if (C1_IO_State == State_In)
            {
                if (getInputBitC1()) { LEDC1.image = (int)LED.LED22.LEDColor.RedOff; }
                else { LEDC1.image = (int)LED.LED22.LEDColor.RedOn; }
            }

            if (C2_IO_State == State_In)
            {
                if (getInputBitC2()) { LEDC2.image = (int)LED.LED22.LEDColor.RedOff; }
                else { LEDC2.image = (int)LED.LED22.LEDColor.RedOn; }
            }

            if (C3_IO_State == State_In)
            {
                if (getInputBitC3()) { LEDC3.image = (int)LED.LED22.LEDColor.RedOff; }
                else { LEDC3.image = (int)LED.LED22.LEDColor.RedOn; }
            }
        }

        #endregion

        #region Bit-bang Output

        private void bitBangOutD(byte Out)
        {
            SM.bitBang_SetBitMode(handle, Out, 0x01);
        }
        
        private void bitBangOutC(byte Out)
        {
            SM.bitBang_SetBitMode(handle, Out, 0x20);
        }

        #endregion

    }
}